home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / pmode / code32 / start32.doc < prev    next >
Text File  |  1993-01-08  |  15KB  |  318 lines

  1.  
  2.   Hi folks, this is Tran... This text explains START32, my 386 protected
  3. mode header... I'm assuming youre an assembler programmer. If you are not,
  4. this thing will do you no good. I'm also assuming you have some experience,
  5. and knowledge of the 386 wouldn't hurt either... If you don't know the 386,
  6. I suggest you get a good book if you really want to code it...
  7.  
  8.  
  9. First of all:
  10. -------------
  11.    I coded START32 for myself, it is designed and optimized for my needs. The
  12. greatest of which is the need for speed... That is the reason I do not
  13. implement paging in this thing, too slow... Also, since the only real mode
  14. INTs I usually need are DOS file functions, the V86 handler is not perfect,
  15. but it does DOS and BIOS just fine.
  16.  
  17.  
  18. What it does:
  19. -------------
  20.    START32 is a piece of code that handles most of the things associated with
  21. using and getting into and out of 32bit protected mode. It also allows your
  22. protected mode programs to access the regular real-mode DOS and BIOS functions.
  23. START32 will check mundane little things like the processor and memory, then
  24. if the system is 386+ and not already in protected mode, it will switch the
  25. system into 32bit protected mode. In protected mode the system will run in
  26. flat memory, that is you won't need to bother with segment registers, and
  27. large data arrays will be much easier to handle...
  28.  
  29.  
  30. How the system works:
  31. ---------------------
  32.    After START32 initializes protected mode, it will jump to a label '_main',
  33. which mush be declared public in your code. This is the starting point of your
  34. program. All of the code and data in your program will reside in one large
  35. segment called 'code32' ... this is a 4gig segment. You do regular code using
  36. the 386 instruction set. To access a real-mode interrupt function, you load
  37. up 'virtual registers' with the values you want passed to the interrupt, then
  38. you load up AL with the number of the interrupt you wanna call, then you call
  39. INT 30h. The system will use the 386's v86 mode to call the real mode int.
  40. After which, the values in the 'virtual regs' will be what the interrupt
  41. handler passed back (All the real registers are preserved).
  42.  
  43.  
  44. Selectors:
  45. ----------
  46.    Instead of physical segment pointers, in protected mode, the 386 uses
  47. selectors. Selectors are indexes into a table of data that describe the
  48. memory location the specific index points to. But you need not concern
  49. yourself with these tables (GDT, IDT, LDTs)... This thing takes care of them.
  50. All you need to know, is that there are 3 basic selectors available to you.
  51. 8, 10h, and 18h... 8 is the selector for the code segment, this is the 4gig
  52. segment which you put all your flat code into. 10h is the selector for the
  53. data segment, the memory is physically the same as the code segment, but
  54. it must be done this way. That is 8 and 10h point to the same large segment,
  55. but CS must use 8, and the data segregs must use 10h... 18h is a data
  56. selector that points to the beginning of memory. 8 and 10h both start at the
  57. beginning of the segment 'code32' in memory, wherever it may be. But 18h
  58. always starts at absolute physical adress 0000:0000... This is in case you
  59. want to access something that resides before the beginning of the 32bit code,
  60. like the BIOS data area or the PSP... Upon arrival at '_main', CS ofcourse is
  61. 8. DS, ES, FS, and SS are 10h. And GS is 18h. And you should keep them this
  62. way because START32, whose job is by far not done after it passes control to
  63. your code, expects it this way.
  64.  
  65.  
  66. IRQs:
  67. -----
  68.    START32 handles IRQs for both the real system, and your protected mode code.
  69. By default, all the IRQ functions point to a piece of code in START32 which
  70. redirects them to their real-mode handler. You can set your own protected mode
  71. IRQ handlers, and control will pass DIRECTLY to them when they are called.
  72. There are four possible scenarios between the type of IRQ handler and the
  73. mode the IRQ was called in. The handling procedure can be the original real
  74. mode handler, or your own protected mode handler. And the IRQ can occur in
  75. protected mode, or when the system is servicing a V86 real mode INT. For
  76. this reason, your protected mode IRQ handler should make no assumption about
  77. the state of the system. That is, upon entry your handler, the only things
  78. you can be sure of, is CS=8, and SS=10h... You must set the other segregs
  79. manually if you wish to use them. Also, you must remember to terminate your
  80. IRQ routine with an 'IRETD' instead of an 'IRET'. If you wish to call the
  81. original real mode handler from your protected mode handler, simply call the
  82. real mode int associated with that IRQ from your handler.
  83.  
  84. BTW: No real mode interrupt vektor table entries are modified by START32, all
  85.  the IRQs go through the IDT.
  86.  
  87. Also: START32 will mask off IRQ 0 and 1 when it first starts. The system timer
  88.  and keyboard IRQs, because there is really no use for them untill you put
  89.  them to use.
  90.  
  91.  
  92. Memory:
  93. -------
  94.    Like I said, the whole system uses flat memory when you use START32. There
  95. are 2 types, low memory - below 640k, and high memory - above 1M... START32
  96. does some very basic 'memory management', if you could call it that. You
  97. can request blocks of a certain size, and START32 will either give ya a
  98. pointer to the block, or tell ya theres not enough of that type of memory.
  99. The blocks are allocated from the bottom up. You cannot free a memory below
  100. an area that you allocated later. You CAN free memory though, simply by
  101. decreasing the 'base of memory' pointer START32 uses to track the current
  102. base of usable memory. This pointer (along with a few others) is made available
  103. to your program. One good way of using this in a function, is along with any
  104. registers you PUSH, you also PUSH the pointer to the type of memory you
  105. wanna use. After the function is done and there is no more use for the memory
  106. it has allocated, you POP the pointer. If you need any memory area permanently
  107. throught the program, you should allocate it at the beginning, and ofcourse
  108. never decrease the pointer beyond this area.
  109.  
  110.  
  111. Crashes:
  112. --------
  113.    One thing about coding protected mode, you do not have the use of a
  114. debugger in finding bugz... Youre gonna have to make due with your own traps
  115. and internal debug aids... But a crash in protected mode is not as bad as in
  116. real mode. START32 handles the 386 exceptions. If any type of exception
  117. occurs, START32 will stop the program, do a debug dump of the exception
  118. number, registers, and stack ... and quit to DOS... The system will very
  119. rarely lock up, and the DOS environment will hardly ever be screwed up...
  120. Some reasons are that like I said, no real mode interrupt vektors are
  121. modified, and any area below the beginning of your program is usually only
  122. accessible through GS. This means that when your code goes astray, it cant
  123. overwrite DOS of the int vect table, or any TSRs below it, or anything. And
  124. there is hardly ever anything that can be screwed up above a program. An
  125. exception will usually occur very soon after a screwup in your code. Two of
  126. the most common exceptions are:
  127.  
  128. 6   - an invalid opcode. Either something overwrote your code, or you code
  129.       jumped off into limbo...
  130. 0dh - a general protection violation. Many things can cause this.
  131.  
  132.  
  133. The system itself:
  134. ------------------
  135.    First of all, START32 expects: CS=8, DS=ES=SS=FS=10h, GS=18h, and the
  136. direction flag cleared when you call any of its functions.
  137.  
  138.  
  139. In the included source code, at the top, the values are:
  140.  
  141.   LOWMIN - the minimum amount of free low memory (minus the code) that
  142.            has to be present for START32 to allow the program to run.
  143.  
  144.   EXTMIN - the minimum amount of extended memory that has to be present
  145.            for START32 to allow the program to run. (START32 will also quit
  146.            if it finds less than 638k total low memory).
  147.  
  148.   TSTAK  - the total stack space for START32 to give. The default value of
  149.            400h bytes is usually enough, unless you plan to do recursion.
  150.  
  151.   ISTAK  - the amount of stack space to be given to a protected mode IRQ
  152.            handler when an IRQ comes from V86 mode. (This also includes
  153.            START32's exception handlers).
  154.  
  155.  
  156. START32 detects and will not run if a VGA is not present. This is not some
  157. system critical thing, but like I said, I wrote START32 for myself, and since
  158. I dont code anything that doesnt require a VGA right now, this is technically
  159. part of the system for me.
  160.  
  161.  
  162. START32 makes these variables available to your program:
  163.  
  164.   _totalextmem:word - The total amount of extended memory in the system (in K).
  165.  
  166.   _code16a:dword - Offset of the beginning of the program from absolute 0.
  167.                    This starts 100h bytes above the PSP.
  168.  
  169.   _code32a:dword - Offset of the beginning of protected mode code from
  170.                    absolute 0. This is useful for creating realative pointers
  171.                    to physical locations. That is if you wanted a pointer to
  172.                    the beginning of the VGA grafix area, realative to DS,
  173.                    move 0A0000h into a reg, then subtract _code32a from it.
  174.                    theres a macro provided to create such pointers, @rlp.
  175.  
  176.   _hextbl:bytes - Simply '0123456789ABCDEF'. It is used during an exception
  177.                   dump, but since it's there, might as well make it public
  178.                   since its so useful in printing hex numbers.
  179.  
  180.   _lomembase:dword - Current base of low memory (as a realative pointer, like
  181.                      all the other regular pointers in your code)... this is
  182.                      the beginning of free low memory that has not been
  183.                      allocated.
  184.  
  185.   _lomemtop:dword - Top of low memory as a realative pointer.
  186.  
  187.   _himembase:dword - Base of high memory, just like _lomembase.
  188.  
  189.   _himemtop:dword - Guess...
  190.  
  191.  
  192.   v86r_ax, v86r_bx, v86r_cx, v86r_dx, v86r_si, v86r_di, v86r_bp, v86r_ds,
  193.   v86r_es, v86r_ah, v86r_al, v86r_bh, v86r_bl, v86r_ch, v86r_cl, v86r_dh,
  194.   v86r_dl, v86r_flags
  195.  
  196.     These are the 'virtual registers' you use to communicate with real-mode
  197.     ints... v86r_flags though is used only to pass BACK flags, flags are not
  198.     set to it before invoking the V86 int...
  199.  
  200.  
  201. Here are some 'functions':
  202.  
  203. ------------------------------------------------------------------------------
  204.   _exit - Exit to real mode.
  205.  
  206. ------------------------------------------------------------------------------
  207.   _ret - Simply points to a RET instruction.
  208.  
  209. ------------------------------------------------------------------------------
  210.   _getvect - Get interrupt vektor, vektors 0-1fh and 30h are reserved, 31h+
  211.              dont exist, but 20h-2fh are IRQ's 0-0fh.
  212.     In:
  213.       BL - interrupt number
  214.     Out:
  215.       EAX - 32 bit offset in code
  216.  
  217. ------------------------------------------------------------------------------
  218.   _setvect - Set interrupt vektor.
  219.     In:
  220.       BL - interrupt number
  221.       EAX - 32 bit offset in code
  222.  
  223. ------------------------------------------------------------------------------
  224.   _getlomem - Get a low memory block.
  225.     In:
  226.       EAX - size requested
  227.     Out:
  228.       CF=1  - not enough mem  (carry flag set)
  229.         EAX - ?
  230.       CF=0  - memory allocated  (carry flag clear)
  231.         EAX - linear pointer to mem
  232.  
  233. ------------------------------------------------------------------------------
  234.   _gethimem - Get a high memory block.
  235.     In:
  236.       EAX - size requested
  237.     Out:
  238.       CF=1  - not enough mem
  239.         EAX - ?
  240.       CF=0  - memory allocated
  241.         EAX - linear pointer to mem
  242.  
  243. ------------------------------------------------------------------------------
  244.   _getmem - Allocate any mem (first cheks low, then high).
  245.     In:
  246.       EAX - size requested
  247.     Out:
  248.       CF=1  - not enough mem
  249.         EAX - ?
  250.       CF=0  - memory allocated
  251.         EAX - linear pointer to mem
  252.  
  253. ------------------------------------------------------------------------------
  254.   _lomemsize - Get amount of low mem free.
  255.     Out:
  256.       EAX - number of bytes free
  257.  
  258. ------------------------------------------------------------------------------
  259.   _himemsize - Get amount of high mem free.
  260.     Out:
  261.       EAX - number of bytes free
  262.  
  263. ------------------------------------------------------------------------------
  264.   _putdosmsg - Put a '$' terminated DOS string.
  265.     In:
  266.       EDX -> message (MUST be in low mem).
  267.  
  268.  
  269. How to use it:
  270. --------------
  271.    It's very simple, you compile START32. Compile with multiple passes to
  272. resolve forward references. Then you link it with your other 32bit modules.
  273. START32 must be the first program in the link list. Try compiling and linking
  274. the example programs, then run them to make sure it runs on your system. The
  275. thing will just color the screen and pop up some numbers, press ESC to return
  276. to DOS.
  277.  
  278.  
  279. Some quickie tips on the 386 instruction set:
  280. ---------------------------------------------
  281. (This isn't anything new to those of you already familiar with it)
  282.  
  283. First the extended registers: EAX,EBX,ECX,EDX,ESI,EDI,EBP,ESP,EIP
  284. are all 32bit registers. (No you can't access EIP directly)...
  285.  
  286. The bit shift instructions, SHL, SHR, RCL, ect... accept immediate values
  287. greater than 1 now. This means 'SHL AX,5' is legal.
  288.  
  289. The addressing mode has been extended. You can use a combination of ANY 2 of
  290. the 8 general purpose instructions and an immediate value in addressing. Also
  291. one of the registers can be multiplied by 2,4, or 8 right in the address field
  292. of the instruction youre using. So 'MOV BX,[EAX+ECX*4+78]' is legal.
  293. BTW: This is really good because it allows you to use the 'LEA' instruction
  294.  to perform quick multiplies. Example: 'LEA EAX,[EAX*4+EAX]' is EAX=EAX*5.
  295.  
  296. A version of the 'IMUL' instruction doesn't require preloading registers other
  297. than the one(s) you wanna multiply... examples:
  298. IMUL EAX,71             ; EAX=EAX*71
  299. IMUL EAX,ECX,33         ; EAX=ECX*33
  300.  
  301. You can 'PUSH' immediates... 'PUSH 17983'
  302.  
  303. I don't feel like explaining the double shift SHLD/SHRD instructions or any
  304. of the BT instructions, so if you don't know em, get a book...
  305.  
  306.  
  307.  
  308. ------------------------------------------------------------------------------
  309. Anyways, play with this thing. If you like the flat memory and stuff then
  310. youre free to use this thing in whatever code you do, PD, shareware,
  311. commercial, or whatever...
  312.  
  313. Any questions or anything, you can contact me on the
  314. Sound Barrier BBS (718)979-6629.
  315.  
  316. L8r...
  317.  
  318.